<template>
  <view class="calendar" :style="appThemeStyle">
    <view class="u-calendar">
      <view class="u-calendar__action u-flex u-row-between">
        <view class="u-calendar__action__icon" :class="{ disabled: disabledPrev }">
          <u-icon name="arrow-left" @click="changeMonthHandler(false)"></u-icon>
        </view>
        <view class="u-calendar__action__text">{{ showTitle }}</view>
        <view class="u-calendar__action__icon" :class="{ disabled: disabledNext }">
          <u-icon name="arrow-right" @click="changeMonthHandler(true)"></u-icon>
        </view>
      </view>
      <view class="u-calendar__week-day">
        <view class="u-calendar__week-day__text" v-for="(item, index) in weekDayZh" :key="index">{{item}}</view>
      </view>
      <view class="u-calendar__content">
        <!-- 前置空白部分 -->
        <block v-for="(item, index) in weekdayArr" :key="index">
          <view class="u-calendar__content__item"></view>
        </block>
        <view class="u-calendar__content__item" :class="{ 'active': checkToday(index + 1), 'disabled': openDisAbled(index + 1)}"
          v-for="(item, index) in daysArr" :key="index">
          <view class="u-calendar__content__item__inner">
            <view v-if="checkToday(index + 1)">今天</view>
            <view v-else-if="checkSignedin(index + 1)" class="signedin">
              <u-icon name="checkmark-circle-fill"></u-icon>
            </view>
            <view v-else>{{ index + 1 }}</view>
          </view>
        </view>
      </view>
    </view>
  </view>
</template>
<script>
  import { inArray } from '@/utils/util';

  export default {
    name: 'Calendar',
    // emits: ["update:modelValue", "input", "change"],
    props: {
      // // 通过双向绑定控制组件的弹出与收起
      // value: {
      //   type: Boolean,
      //   default: false
      // },
      // modelValue: {
      //   type: Boolean,
      //   default: false
      // },
      // date-单个日期选择
      mode: {
        type: String,
        default: 'date'
      },
      // 可切换的最大年份
      maxYear: {
        type: [Number, String],
        default: 2050
      },
      // 可切换的最小年份
      minYear: {
        type: [Number, String],
        default: 1950
      },
      // 最小可选日期(不在范围内日期禁用不可选)
      minDate: {
        type: [Number, String],
        default: '1950-01-01'
      },
      /**
       * 最大可选日期
       * 默认最大值为今天，之后的日期不可选
       * 2030-12-31
       */
      maxDate: {
        type: [Number, String],
        default: ''
      },
      yearText: {
        type: String,
        default: '年'
      },
      monthText: {
        type: String,
        default: '月'
      },
      // 已签到的时期 20250301
      signinData: {
        type: Array,
        default: []
      },
    },
    data() {
      return {
        // popupValue: false,
        // 星期几, 值为 1-7
        weekday: 1,
        weekdayArr: [],
        // 当前月有多少天
        days: 0,
        daysArr: [],
        showTitle: '',
        year: 2020,
        month: 0,
        day: 0,
        today: '',
        // 当前选中的日期 (默认是今天)
        activeDate: '',
        min: null,
        max: null,
        weekDayZh: ['日', '一', '二', '三', '四', '五', '六'],
        // 现在的月份
        nowMonth: 0,
        // 禁止向上切换月份
        disabledPrev: false,
        // 禁止向下切换月份
        disabledNext: false
      };
    },
    computed: {
      // valueCom() {
      //   // #ifdef VUE2
      //   return this.value;
      //   // #endif

      //   // #ifdef VUE3
      //   return this.modelValue;
      //   // #endif
      // },
      dataChange() {
        return `${this.mode}-${this.minDate}-${this.maxDate}`;
      }
    },
    watch: {
      dataChange(val) {
        this.init()
      },
      // valueCom: {
      //   immediate: true,
      //   handler(val) {
      //     this.popupValue = val;
      //   }
      // }
    },
    created() {
      this.init()
    },
    methods: {
      // 数据初始化
      init() {
        let now = new Date();
        this.year = now.getFullYear();
        this.month = now.getMonth() + 1;
        this.nowMonth = now.getMonth() + 1;
        this.day = now.getDate();
        this.today = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()}`;
        this.activeDate = this.today;
        this.min = this.initDate(this.minDate);
        this.max = this.initDate(this.maxDate || this.today);
        this.changeData();
      },
      // 日期处理
      initDate(date) {
        let fdate = date.split('-');
        return {
          year: Number(fdate[0] || 1920),
          month: Number(fdate[1] || 1),
          day: Number(fdate[2] || 1)
        }
      },
      // 验证是否为今天
      checkToday(vDay) {
        return this.today == `${this.year}-${this.month}-${vDay}`
      },
      // 验证是否已签到
      checkSignedin(vDay) {
        const year = this.year.toString().padStart(4, "0");
        const month = this.month.toString().padStart(2, "0");
        const day = vDay.toString().padStart(2, "0");
        return inArray(`${year}${month}${day}`, this.signinData)
      },
      // 判断日期是否可选
      openDisAbled(vDay) {
        const timestamp = new Date(`${this.year}-${this.month}-${vDay}`).getTime();
        return timestamp < new Date(this.today).getTime()
      },
      generateArray(start, end) {
        return Array.from(new Array(end + 1).keys()).slice(start);
      },
      formatNum(num) {
        return num < 10 ? '0' + num : num + '';
      },
      // 一个月有多少天
      getMonthDay(year, month) {
        let days = new Date(year, month, 0).getDate();
        return days;
      },
      getWeekday(year, month) {
        let date = new Date(`${year}/${month}/01 00:00:00`);
        return date.getDay();
      },
      checkRange(year) {
        let overstep = false;
        if (year < this.minYear || year > this.maxYear) {
          uni.showToast({
            title: "日期超出范围啦~",
            icon: 'none'
          })
          overstep = true;
        }
        return overstep;
      },
      // 切换月份事件
      changeMonthHandler(isNext = true) {
        if (isNext) {
          const month = this.month + 1;
          let year = month > 12 ? this.year + 1 : this.year;
          if (!this.disabledNext && !this.checkRange(year)) {
            this.month = month > 12 ? 1 : month;
            this.year = year;
            this.changeData();
          }
        } else {
          const month = this.month - 1;
          let year = month < 1 ? this.year - 1 : this.year;
          if (!this.disabledPrev && !this.checkRange(year)) {
            this.month = month < 1 ? 12 : month;
            this.year = year;
            this.changeData();
          }
        }
      },
      changeData() {
        this.days = this.getMonthDay(this.year, this.month);
        this.daysArr = this.generateArray(1, this.days)
        this.weekday = this.getWeekday(this.year, this.month);
        this.weekdayArr = this.generateArray(1, this.weekday)
        this.showTitle = `${this.year}${this.yearText}${this.month}${this.monthText}`;
        // 判断月份选择禁用 (仅允许查看 上月、当月、下月)
        this.disabledPrev = this.month - 1 <= this.nowMonth - 2
        this.disabledNext = this.month + 1 >= this.nowMonth + 2
      },
      // 日期项点击事件
      dateClick(day) {
        day += 1;
        if (!this.openDisAbled(this.year, this.month, day)) {
          this.day = day;
          let date = `${this.year}-${this.month}-${day}`;
          if (this.mode == 'date') {
            this.activeDate = date;
          }
        }
      },
      getWeekText(date) {
        date = new Date(`${date.replace(/\-/g, '/')} 00:00:00`);
        let week = date.getDay();
        return '星期' + ['日', '一', '二', '三', '四', '五', '六'][week];
      }
    }
  }
</script>

<style lang="scss" scoped>
  @import "@/uni_modules/vk-uview-ui/libs/css/style.components.scss";

  .u-calendar {
    // color: $u-content-color;
    background-color: #fff;
    padding: 0 20rpx;
    border-radius: 30rpx;

    &__action {
      padding: 40rpx 0;

      &__icon {
        margin: 0 16rpx;
        color: #434343;
        font-size: 32rpx;

        &.disabled {
          color: #cacaca;
        }
      }

      &__text {
        padding: 0 12rpx;
        color: $u-main-color;
        font-size: 32rpx;
        line-height: 32rpx;
        font-weight: bold;
      }
    }

    &__week-day {
      @include vue-flex;
      align-items: center;
      justify-content: center;
      padding: 12rpx 0;
      overflow: hidden;
      font-size: 26rpx;
      color: #999999;

      &__text {
        flex: 1;
        text-align: center;
      }
    }

    &__content {
      width: 100%;
      @include vue-flex;
      flex-wrap: wrap;
      padding: 12rpx 0;
      box-sizing: border-box;
      position: relative;

      &__item {
        width: 14.2857%;
        @include vue-flex;
        align-items: center;
        justify-content: center;
        padding: 8rpx 0;
        overflow: hidden;
        position: relative;
        z-index: 2;
        border-radius: 12rpx;
        color: #000;

        &.disabled {
          color: #999999;
        }

        &.active {
          font-weight: bold;
        }

        &__inner {
          height: 84rpx;
          @include vue-flex;
          align-items: center;
          justify-content: center;
          flex-direction: column;
          font-size: 28rpx;
          position: relative;
          border-radius: 50%;

          .signedin {
            color: $main-bg;
            font-size: 42rpx;
          }
        }

      }

    }

  }
</style>